package com.yunzai.chat.endpoint;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.yunzai.generic.domain.JSONResult;
import com.yunzai.onebot.domain.OneBotMessage;
import com.yunzai.onebot.domain.SenderInfo;
import com.yunzai.onebot.service.IOneBotService;
import com.yunzai.secure.domain.LoginUser;
import com.yunzai.secure.service.ITokenService;
import com.yunzai.secure.util.SecurityUtil;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/chat/ws")
@Component
public class ChatEndpoint {

    private static final Logger log = LoggerFactory.getLogger(ChatEndpoint.class);

    public static IOneBotService oneBotService;

    public static ITokenService tokenService;

    private static final Gson gson = new Gson();

    // 使用线程安全的 Map 存储所有客户端 Session
    private static final ConcurrentHashMap<Long, Session> sessions = new ConcurrentHashMap<>();

    // 使用定时任务替代轮询（Spring Scheduler）
    @Scheduled(fixedRate = 2000)
    public void checkMessages() {
        sessions.forEach((id, session) -> {
            if (session.isOpen()) {
                try {
                    List<JsonObject> messages = oneBotService.getNewMessage(id);
                    if (!messages.isEmpty()) {
                        session.getAsyncRemote().sendText(messages.toString());
                    }
                } catch (Exception e) {
                    sessions.remove(id);
                    log.error("发送消息失败: {}, {}", id, e.getMessage());
                }
            }
        });
    }

    // 连接建立时保存 Session
    @OnOpen
    public void onOpen(Session session) {
        log.info("客户端连接: {}", session.getId());
    }

    // 添加心跳处理
    @OnMessage
    public void onMessage(String message, Session session) {
        JsonObject json = gson.fromJson(message, JsonObject.class);
        // 处理认证消息
        if ("auth".equals(json.get("type").getAsString())) {
            String token = json.get("token").getAsString();
            Long userId = tokenService.getLoginUser(token).getId();
            sessions.put(userId, session);
            log.info("用户 {} 认证成功", userId);
        } else
        //处理心跳消息
        if ("heartbeat".equals(json.get("type").getAsString())) {
            JsonObject jsonObject = new JsonObject();
            jsonObject.addProperty("type", "pong");
            session.getAsyncRemote().sendText(jsonObject.toString());
//            log.info("接收到心跳消息：{}", jsonObject);
        } else
        //向云崽发送文本消息
        if("send_msg".equals(json.get("type").getAsString())) {
            String token = json.get("token").getAsString();
            String msg = json.get("message").getAsString();
            LoginUser loginUser = tokenService.getLoginUser(token);
            if (loginUser == null) {
                return;
            }
            Long id = loginUser.getId();
            String nickname = loginUser.getNickname();
            OneBotMessage oneBotMessage = new OneBotMessage();
            oneBotMessage.setUser_id(id);
            oneBotMessage.setMessage(msg);
            oneBotMessage.setRaw_message(msg);

            SenderInfo senderInfo = new SenderInfo();
            senderInfo.setUser_id(id);
            senderInfo.setNickname(nickname);

            oneBotMessage.setSender(senderInfo);
            oneBotService.sendMessage(JSONResult.toJSONString(oneBotMessage));
        } else if ("upload_private_file".equals(json.get("type").getAsString())) {
            String token = json.get("token").getAsString();
            String msg = json.get("message").getAsString();
            LoginUser loginUser = tokenService.getLoginUser(token);
            if (loginUser == null) {
                return;
            }
            Long id = loginUser.getId();
            String nickname = loginUser.getNickname();
        }
    }

    // 连接关闭时移除 Session
    @OnClose
    public void onClose(Session session) {
        sessions.forEach((id, val) -> {
            if (session.getId().equals(val.getId())) {
                sessions.remove(id);
                log.info("客户端断开: {}", id);
            }
        });
    }
}
